#include "log.h"
#include <string.h>
#include "log4cpp/Category.hh"
#include "log4cpp/RollingFileAppender.hh"
#include "log4cpp/PatternLayout.hh"
#include "log4cpp/OstreamAppender.hh"

namespace common
{

	int32_t InitLog(const char* log_name,
		const char* log_dir,
		LogLevel priority,
		uint32_t max_file_zie,
		uint32_t max_backup_index,
		bool append)
	{
		if (NULL == log_name || NULL == log_dir)
		{
			return -1;
		}
		// 已经存在该名称的实例
		log4cpp::Category* category = log4cpp::Category::exists(log_name);
		if (category != NULL)
		{
			return -2;
		}
		// 1实例化一个layout 对象
		log4cpp::PatternLayout* layout = new log4cpp::PatternLayout();
		layout->setConversionPattern("[%d{%Y-%m-%d %H:%M:%S}] [%p] %m%n");
		// 2. 初始化一个appender 对象
		log4cpp::Appender* appender = new log4cpp::RollingFileAppender(log_name, log_dir, max_file_zie, max_backup_index, append);
		// 3. 把layout对象附着在appender对象上
		appender->setLayout(layout);

		// 4. 实例化一个category对象
		log4cpp::Category& new_category = log4cpp::Category::getInstance(log_name);
		// 5. 设置additivity为false，替换已有的appender
		new_category.setAdditivity(false);
		// 6. 把appender对象附到category上
		new_category.setAppender(appender);
#ifdef _MSC_VER
		// 2. 初始化一个appender 对象
		log4cpp::PatternLayout* layout2 = new log4cpp::PatternLayout();
		layout2->setConversionPattern("[%d{%Y-%m-%d %H:%M:%S}] [%p] %m%n");
		log4cpp::Appender* os_appender = new log4cpp::OstreamAppender("ostream", &std::cout);
		// 3. 把layout对象附着在appender对象上
		os_appender->setLayout(layout2);
		new_category.setAppender(os_appender);
#endif
		// 7. 设置category的优先级，低于此优先级的日志不被记录
		new_category.setPriority((log4cpp::Priority::PriorityLevel) priority);
		new_category.info("log create succeed!");
		return 0;
	}


	/**
	* @brief ShutdownLog 关闭日志文件
	*
	* @param pLogName
	*
	* @return
	*/
	int32_t ShutdownLog(const char* log_name)
	{
		log4cpp::Category* category = log4cpp::Category::exists(log_name);
		if (category != NULL)
		{
			category->removeAppender(category->getAppender(log_name));
		}
		return 0;
	}

	/**
	* @brief ShutdownAllLog 关闭所有日志文件
	*
	* @return
	*/
	int32_t ShutdownAllLog()
	{
		// TODO: 崩溃
		log4cpp::Category::shutdown();
		return 0;
	}

	int32_t Log(const char* log_name, int32_t priority_level, const char* format, ...)
	{
		if (NULL == log_name)
		{
			return -1;
		}
		log4cpp::Category* category = log4cpp::Category::exists(log_name);
		if (NULL == category)
		{
			char str[256] = { 0 };
			va_list parame;
			va_start(parame, format);
			vsnprintf(str, sizeof(str), format, parame);
			va_end(parame);
			printf("%s\n", str);
			return -2;
		}
		va_list va;
		va_start(va, format);
		category->logva(priority_level, format, va);
		va_end(va);
		return 0;
	}


	int log_va(const char* vLogName, int vPriority, const char* vFmt, va_list ap)
	{
		if (NULL == vLogName)
		{
			return -1;
		}

		log4cpp::Category* tpCategory = log4cpp::Category::exists(vLogName);
		if (NULL == tpCategory)
		{

			char str[256] = { 0 };
			vsnprintf(str, sizeof(str), vFmt, ap);
			printf("%s\n", str);

			return -1;
		}

		tpCategory->logva(vPriority, vFmt, ap);

		return 0;
	}

}
